#pragma once
/*
缓冲区：
功能:暂时接收工作线程发送的日志信息

提供接口:
write接口:外界向缓冲区插入数据
begin();//可写位置指针
AbleWriteSize();//可写空间
AbleReadSize();//可读空间
moveRead()/moveWrite();//读写指针移动
reset();//复位
swap();//交换
成员:
vector<char>
read_index;
write_index;
*/
#include <iostream>
#include <vector>
#include <cassert>
namespace LoggerSpace
{
#define DEFAULT_BUFFER_SIZE 1* 1024 * 1024      // 1M
#define DEFAULT_BUFFER_THRESHOLD 16 * 1024 * 1024 // 16M//阈值
#define DEFAULT_BUFFER_INCREMENT 1 * 1024 * 1024 // 1M//增量

    class Buffer
    {
    public:
        Buffer(size_t cap = DEFAULT_BUFFER_SIZE) : _q(cap) {}
        bool write(const char *str, int len)
        {
            // 如果可写空间不够?
            // 返回false,由外部来做决定
            //  if(len>AbleWriteSize())
            //  return false;
            // 先确保有足够的空间
            EableEnoughSpace(len);
            // 进行拷贝
            std::copy(str, str + len, _q.begin() + _write_index);
            // 更新write指针
            moveWrite(len);
            return true;
        }
        const char *begin()
        {
            return &_q[_read_index];
        }
        // 可写空间
        size_t AbleWriteSize()
        {
            return _q.size() - _write_index;
        }
        // 可读空间大小
        size_t AbleReadSize()
        {
            return _write_index - _read_index;
        }
        void swap(Buffer &bf)
        {
            _q.swap(bf._q);
            std::swap(_write_index, bf._write_index);
            std::swap(_read_index, bf._read_index);
        }
        void reset()
        {
            _write_index = _read_index = 0;
        }

        void moveRead(size_t len)
        {
            assert(len + _read_index <= _write_index);
            _read_index += len;
        }
        bool empty()
        {
            return _write_index == _read_index;
        }

    private:
        void moveWrite(size_t len)
        {
            assert(_write_index + len <= _q.size());
            _write_index += len;
        }
        void EableEnoughSpace(int len)
        {
            if (len > AbleWriteSize())
            {
                //
                size_t newSize = _q.size() < DEFAULT_BUFFER_THRESHOLD ? 2 * _q.size() : _q.size() + DEFAULT_BUFFER_INCREMENT;
                _q.resize(newSize);
            }
        }
        std::vector<char> _q;
        size_t _read_index = 0;
        size_t _write_index = 0;
    };

} // namespace MySpace
